Skip to content

Add camera presets to the Sandbox - #18807

Draft
VicenteCartas wants to merge 10 commits into
BabylonJS:masterfrom
VicenteCartas:sandbox-improvement
Draft

Add camera presets to the Sandbox#18807
VicenteCartas wants to merge 10 commits into
BabylonJS:masterfrom
VicenteCartas:sandbox-improvement

Conversation

@VicenteCartas

@VicenteCartas VicenteCartas commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

🤖 This PR was created by the create-pr skill.

Summary

  • Add an Inspector section for saving camera configurations as named presets
  • Persist camera, input, and behavior settings locally and restore the selected preset across model loads
  • Add a camera-bookmark footer selector with a Default camera recovery option
  • Preserve existing embedded-camera, Reflector, texture-preview, and no-preset behavior
  • Honor explicit URL camera and camera-position overrides without clearing the saved preset preference
  • Add portable cameraMinZ and cameraLowerRadiusLimit URL parameters for large-scene debugging
  • Keep numeric URL limits active across in-page model reloads while allowing the local preset to resume after the first model load
  • Surface preset save/application failures through the existing Sandbox error UI

Motivation

The Sandbox's conservative camera limits work well for product-scale assets, but make it difficult to inspect large scenes such as cities. User-defined presets provide a reusable local workflow, while explicit numeric URL limits let admin/debug links work immediately in a clean browser without changing defaults for occasional Sandbox users.

Related discussion: https://forum.babylonjs.com/t/debugging-large-scenes-in-sandbox/63955

Companion documentation: BabylonJS/Documentation#1609

Versioned runtime compatibility

  • ?version=8.40.1 runs the current Sandbox application bundle against the Babylon.js 8.40.1 dependency set, including Inspector V2; it does not load a historical Sandbox application.
  • 8.40.1 is the oldest runtime for which the Sandbox bootstrap selects Inspector V2. The full save-and-activate workflow is directly validated against 8.40.1, 8.51.0, and current.
  • The required Inspector host-extension exports exist in 8.40.1. The Sandbox still detects each capability at runtime; if any are absent, Inspector opens normally without the Save Camera Preset section.
  • Preset persistence uses the historical DataStorage.ReadString / WriteString API because ReadJson / WriteJson were introduced after 8.40.1.

URL parameters

  • cameraMinZ=<number> sets the near clipping plane on the final active camera. The value must be finite and greater than 0.
  • cameraLowerRadiusLimit=<number> sets the minimum orbit radius when the final active camera is an ArcRotateCamera. The value must be finite and greater than or equal to 0.

Valid numeric camera settings suppress an active browser-local preset for the first model load without deleting it. The numeric limits continue to apply to later model loads or R reloads while the page remains open, even if the saved preset resumes.

Example:

https://sandbox.babylonjs.com/?asset=https://assets.babylonjs.com/meshes/boombox.glb&cameraMinZ=0.01&cameraLowerRadiusLimit=0

Validation

  • 21 focused URL/state Vitest tests plus the existing camera-preset unit coverage
  • 13 isolated camera-preset Playwright scenarios, including numeric limits, R reload persistence, invalid values, embedded cameras, URL precedence, and texture previews
  • Sandbox TypeScript compile and deployment build
  • Repository format, lint, tree-shaking, side-effect, diagnostics, and diff checks
  • Full Monorepo and Playground/Sandbox CI passed before the URL follow-up; follow-up checks are running

Screenshots

Saving a camera preset
image

When you have presets, they appear on the bottom right UI:
image

URL overrides for min z and lower radius limit:
image

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@bjsplat

bjsplat commented Aug 15, 2026

Copy link
Copy Markdown
Collaborator

Please make sure to label your PR with "bug", "new feature" or "breaking change" label(s).
To prevent this PR from going to the changelog marked it with the "skip changelog" label.

@bjsplat

bjsplat commented Aug 15, 2026

Copy link
Copy Markdown
Collaborator

Building or testing the sandbox has failed.

If the tests failed, results can be found here:
https://snapshots-cvgtc2eugrd3cgfd.z01.azurefd.net/SANDBOX/refs/pull/18807/merge/testResults/

@bjsplat

bjsplat commented Aug 15, 2026

Copy link
Copy Markdown
Collaborator

Snapshot stored with reference name:
refs/pull/18807/merge

Test environment:
https://snapshots-cvgtc2eugrd3cgfd.z01.azurefd.net/refs/pull/18807/merge/index.html

To test a playground add it to the URL, for example:

https://snapshots-cvgtc2eugrd3cgfd.z01.azurefd.net/refs/pull/18807/merge/index.html#WGZLGJ#4600

Links to test your changes to core in the published versions of the Babylon tools (does not contain changes you made to the tools themselves):

https://playground.babylonjs.com/?snapshot=refs/pull/18807/merge
https://sandbox.babylonjs.com/?snapshot=refs/pull/18807/merge
https://gui.babylonjs.com/?snapshot=refs/pull/18807/merge
https://nme.babylonjs.com/?snapshot=refs/pull/18807/merge

To test the snapshot in the playground with a playground ID add it after the snapshot query string:

https://playground.babylonjs.com/?snapshot=refs/pull/18807/merge#BCU1XR#0

If you made changes to the sandbox or playground in this PR, additional comments will be generated soon containing links to the dev versions of those tools.

@bjsplat

bjsplat commented Aug 15, 2026

Copy link
Copy Markdown
Collaborator

You have made possible changes to the playground.
You can test the snapshot here:

https://snapshots-cvgtc2eugrd3cgfd.z01.azurefd.net/PLAYGROUND/refs/pull/18807/merge/

The snapshot playground with the CDN snapshot (only when available):

https://snapshots-cvgtc2eugrd3cgfd.z01.azurefd.net/PLAYGROUND/refs/pull/18807/merge/?snapshot=refs/pull/18807/merge

Note that neither Babylon scenes nor textures are uploaded to the snapshot directory, so some playgrounds won't work correctly.

@bjsplat

bjsplat commented Aug 15, 2026

Copy link
Copy Markdown
Collaborator

@bjsplat

bjsplat commented Aug 15, 2026

Copy link
Copy Markdown
Collaborator

@bjsplat

bjsplat commented Aug 15, 2026

Copy link
Copy Markdown
Collaborator

⚡ Performance Test Results

🟢 All performance tests passed — no regressions detected.

@bjsplat

bjsplat commented Aug 15, 2026

Copy link
Copy Markdown
Collaborator

@bjsplat

bjsplat commented Aug 15, 2026

Copy link
Copy Markdown
Collaborator

🟢 Memory Leak Test Results

4 passed, 0 leaked out of 4 scenarios

🟢 All memory leak tests passed — no leaks detected.

Passed Scenarios (4)
Scenario Package
Core Playground #2FDQT5#1508 @babylonjs/core
Core Playground #T90MQ4#14 @babylonjs/core
Core Playground #8EDB5N#2 @babylonjs/core
Core Playground #LL5BIQ#636 @babylonjs/core

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@VicenteCartas
VicenteCartas marked this pull request as ready for review August 15, 2026 06:32
@VicenteCartas

Copy link
Copy Markdown
Contributor Author

Self code review completed by the code-review skill. Review fixes: adc03bf0c1

  • Added validation coverage for malformed storage, unsafe name suffixes, and unavailable camera types
  • Made camera preset state persistence transactional and surfaced user-triggered failures through the Sandbox error UI
  • Preserved explicit URL camera and camera-position overrides while retaining the saved preset preference
  • Simplified behavior restoration and clarified Inspector section ordering and interaction-test setup
  • Verified format, lint/tree-shaking checks, 15 focused unit tests, Sandbox build, and the targeted Playwright workflow

Copilot AI lite review requested due to automatic review settings August 15, 2026 06:32

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds end-user camera presets to the Babylon.js Sandbox, enabling saving/restoring camera configurations (including inputs and certain behaviors) and integrating preset management into the Inspector and the footer UI, with persistence via local storage.

Changes:

  • Introduces CameraPresetManager for serializing, persisting, restoring, and applying camera presets (plus behavior state for ArcRotateCamera).
  • Adds an Inspector “Save Camera Preset” section and a footer “Select camera preset” dropup (including a “Default camera” recovery option).
  • Expands unit + Playwright coverage for saving/applying presets, persistence across reloads, and URL override behavior.

Reviewed changes

Copilot reviewed 12 out of 13 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
packages/tools/sandbox/src/tools/cameraPresetManager.ts New preset storage, parsing, persistence, and apply/activate/deactivate logic for cameras + behaviors.
packages/tools/sandbox/src/tools/cameraPresetInspectorService.tsx New Inspector service definition adding a “Save Camera Preset” section when a camera is selected.
packages/tools/sandbox/src/components/footer.tsx Footer now tracks cameras/presets, adds camera preset selector UI, and cleans up observers on unmount.
packages/tools/sandbox/src/components/renderingZone.tsx Applies active preset on scene loads (when appropriate), emits camera-changed events, and tracks texture-preview scenes.
packages/tools/sandbox/src/globalState.ts Adds camera/preset-related global state, new observables, and wires Inspector service definitions into ShowInspector.
packages/tools/sandbox/src/sandbox.tsx Tracks load-kind and “scene had cameras” flags; marks URL camera overrides as preset-override cases.
packages/tools/sandbox/src/components/reflectorZone.tsx Updates onSceneLoaded payload to include load kind.
packages/tools/sandbox/src/scss/footer.scss Adds .longest footer layout variant to accommodate the new control.
packages/tools/sandbox/src/main.ts Adjusts dev-only inspector import to inspector/legacy/legacy.
packages/tools/sandbox/src/img/icon-camera-preset.svg Adds new camera preset icon asset for the footer UI.
packages/tools/sandbox/test/unit/cameraPresetManager.test.ts Adds unit tests for naming, parsing, persistence failures, and camera/behavior round-tripping.
packages/tools/sandbox/test/unit/footer.test.tsx Adds unit test covering footer camera/preset control enablement and observer cleanup.
packages/tools/sandbox/test/interaction.sandbox.test.ts Adds Playwright workflow covering saving/selecting/restoring presets and URL override interactions.
Suppressed comments (2)

packages/tools/sandbox/src/tools/cameraPresetManager.ts:214

  • Using toLocaleLowerCase() makes name de-duplication dependent on the user's runtime locale (e.g. Turkish locale casing can change results). For stable, locale-independent comparisons here, use toLowerCase() instead.
    while (normalizedNames.has(`${baseName} ${suffix}`.toLocaleLowerCase())) {
        suffix++;

packages/tools/sandbox/src/tools/cameraPresetManager.ts:203

  • Using toLocaleLowerCase() makes name de-duplication dependent on the user's runtime locale (e.g. Turkish locale casing can change results). For stable, locale-independent comparisons here, use toLowerCase() instead.
    if (!normalizedNames.has(trimmedName.toLocaleLowerCase())) {
        return trimmedName;

💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread packages/tools/sandbox/src/components/renderingZone.tsx
Comment thread packages/tools/sandbox/src/tools/cameraPresetManager.ts
Comment thread packages/tools/sandbox/src/tools/cameraPresetManager.ts Outdated
@bjsplat

bjsplat commented Aug 15, 2026

Copy link
Copy Markdown
Collaborator

Building or testing the sandbox has failed.

If the tests failed, results can be found here:
https://snapshots-cvgtc2eugrd3cgfd.z01.azurefd.net/SANDBOX/refs/pull/18807/merge/testResults/

@bjsplat

bjsplat commented Aug 15, 2026

Copy link
Copy Markdown
Collaborator

Building or testing the playground has failed.

If the tests failed, results can be found here:
https://snapshots-cvgtc2eugrd3cgfd.z01.azurefd.net/PLAYGROUND/refs/pull/18807/merge/testResults/

@bjsplat

bjsplat commented Aug 15, 2026

Copy link
Copy Markdown
Collaborator

⚡ Performance Test Results

🟢 All performance tests passed — no regressions detected.

@bjsplat

bjsplat commented Aug 15, 2026

Copy link
Copy Markdown
Collaborator

@bjsplat

bjsplat commented Aug 15, 2026

Copy link
Copy Markdown
Collaborator

@bjsplat

bjsplat commented Aug 15, 2026

Copy link
Copy Markdown
Collaborator

@bjsplat

bjsplat commented Aug 15, 2026

Copy link
Copy Markdown
Collaborator

🟢 Memory Leak Test Results

4 passed, 0 leaked out of 4 scenarios

🟢 All memory leak tests passed — no leaks detected.

Passed Scenarios (4)
Scenario Package
Core Playground #2FDQT5#1508 @babylonjs/core
Core Playground #T90MQ4#14 @babylonjs/core
Core Playground #8EDB5N#2 @babylonjs/core
Core Playground #LL5BIQ#636 @babylonjs/core

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@bjsplat

bjsplat commented Aug 15, 2026

Copy link
Copy Markdown
Collaborator

You have made possible changes to the playground.
You can test the snapshot here:

https://snapshots-cvgtc2eugrd3cgfd.z01.azurefd.net/PLAYGROUND/refs/pull/18807/merge/

The snapshot playground with the CDN snapshot (only when available):

https://snapshots-cvgtc2eugrd3cgfd.z01.azurefd.net/PLAYGROUND/refs/pull/18807/merge/?snapshot=refs/pull/18807/merge

Note that neither Babylon scenes nor textures are uploaded to the snapshot directory, so some playgrounds won't work correctly.

@bjsplat

bjsplat commented Aug 15, 2026

Copy link
Copy Markdown
Collaborator

@bjsplat

bjsplat commented Aug 18, 2026

Copy link
Copy Markdown
Collaborator

@bjsplat

bjsplat commented Aug 18, 2026

Copy link
Copy Markdown
Collaborator

⚡ Performance Test Results

🟢 All performance tests passed — no regressions detected.

@bjsplat

bjsplat commented Aug 18, 2026

Copy link
Copy Markdown
Collaborator

@bjsplat

bjsplat commented Aug 18, 2026

Copy link
Copy Markdown
Collaborator

You have changed file(s) that made possible changes to the sandbox.
You can test the sandbox snapshot here:

https://snapshots-cvgtc2eugrd3cgfd.z01.azurefd.net/SANDBOX/refs/pull/18807/merge/

@bjsplat

bjsplat commented Aug 18, 2026

Copy link
Copy Markdown
Collaborator

@bjsplat

bjsplat commented Aug 18, 2026

Copy link
Copy Markdown
Collaborator

🟢 Memory Leak Test Results

4 passed, 0 leaked out of 4 scenarios

🟢 All memory leak tests passed — no leaks detected.

Passed Scenarios (4)
Scenario Package
Core Playground #2FDQT5#1508 @babylonjs/core
Core Playground #T90MQ4#14 @babylonjs/core
Core Playground #8EDB5N#2 @babylonjs/core
Core Playground #LL5BIQ#636 @babylonjs/core

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@VicenteCartas

Copy link
Copy Markdown
Contributor Author

Compatibility hardening added in 23b5fd1985, following confirmation that a Sandbox-owned service contribution is the intended Inspector extensibility model.

Dynamic bundle compatibility

  • The oldest Sandbox-selected Inspector V2 runtime (8.40.1) already exposes ShowInspector, PropertiesServiceIdentity, SelectionServiceIdentity, TextInputPropertyLine, ButtonLine, and host serviceDefinitions support.
  • DataStorage.ReadJson / WriteJson were introduced later (8.51.0). Preset persistence and the existing glTF loader-options bridge now use Sandbox-local JSON over the historical ReadString / WriteString floor instead.
  • The Sandbox feature-detects every required Inspector runtime capability. If a loaded Inspector exposes ShowInspector but not the contribution APIs, Inspector opens normally without the Save section. If ShowInspector is absent, the existing debug-layer fallback remains.
  • The contributed service also validates consumed service shapes and cleans up partial registrations defensively rather than crashing the Inspector.

Compatibility matrix

  • 8.40.1: GLB load, footer-opened Inspector, camera selection, Save section, persistence, footer activation, and active camera verified.
  • 8.51.0: same save-and-activate path verified.
  • Current runtime: existing save/activate/reload flow verified.
  • Plain Vite development: historical tests skip explicitly because ?version= is handled only by the production bootstrap; the current-runtime test still runs.

Validation: 59/59 Sandbox unit tests, Sandbox compile/deployment build, production-shaped 3/3 browser matrix, full format/lint/tree-shaking/side-effect checks, and independent review approval.

@bjsplat

bjsplat commented Aug 18, 2026

Copy link
Copy Markdown
Collaborator

Building or testing the playground has failed.

If the tests failed, results can be found here:
https://snapshots-cvgtc2eugrd3cgfd.z01.azurefd.net/PLAYGROUND/refs/pull/18807/merge/testResults/

@bjsplat

bjsplat commented Aug 18, 2026

Copy link
Copy Markdown
Collaborator

Building or testing the sandbox has failed.

If the tests failed, results can be found here:
https://snapshots-cvgtc2eugrd3cgfd.z01.azurefd.net/SANDBOX/refs/pull/18807/merge/testResults/

@bjsplat

bjsplat commented Aug 18, 2026

Copy link
Copy Markdown
Collaborator

@bjsplat

bjsplat commented Aug 18, 2026

Copy link
Copy Markdown
Collaborator

@bjsplat

bjsplat commented Aug 18, 2026

Copy link
Copy Markdown
Collaborator

⚡ Performance Test Results

🟢 All performance tests passed — no regressions detected.

@bjsplat

bjsplat commented Aug 18, 2026

Copy link
Copy Markdown
Collaborator

@bjsplat

bjsplat commented Aug 18, 2026

Copy link
Copy Markdown
Collaborator

🟢 Memory Leak Test Results

4 passed, 0 leaked out of 4 scenarios

🟢 All memory leak tests passed — no leaks detected.

Passed Scenarios (4)
Scenario Package
Core Playground #2FDQT5#1508 @babylonjs/core
Core Playground #T90MQ4#14 @babylonjs/core
Core Playground #8EDB5N#2 @babylonjs/core
Core Playground #LL5BIQ#636 @babylonjs/core

@bjsplat

bjsplat commented Aug 18, 2026

Copy link
Copy Markdown
Collaborator

You have made possible changes to the playground.
You can test the snapshot here:

https://snapshots-cvgtc2eugrd3cgfd.z01.azurefd.net/PLAYGROUND/refs/pull/18807/merge/

The snapshot playground with the CDN snapshot (only when available):

https://snapshots-cvgtc2eugrd3cgfd.z01.azurefd.net/PLAYGROUND/refs/pull/18807/merge/?snapshot=refs/pull/18807/merge

Note that neither Babylon scenes nor textures are uploaded to the snapshot directory, so some playgrounds won't work correctly.

@bjsplat

bjsplat commented Aug 18, 2026

Copy link
Copy Markdown
Collaborator

@bjsplat

bjsplat commented Aug 18, 2026

Copy link
Copy Markdown
Collaborator

⚡ Performance Test Results

🟢 All performance tests passed — no regressions detected.

@bjsplat

bjsplat commented Aug 18, 2026

Copy link
Copy Markdown
Collaborator

@bjsplat

bjsplat commented Aug 18, 2026

Copy link
Copy Markdown
Collaborator

@bjsplat

bjsplat commented Aug 18, 2026

Copy link
Copy Markdown
Collaborator

🟢 Memory Leak Test Results

4 passed, 0 leaked out of 4 scenarios

🟢 All memory leak tests passed — no leaks detected.

Passed Scenarios (4)
Scenario Package
Core Playground #2FDQT5#1508 @babylonjs/core
Core Playground #T90MQ4#14 @babylonjs/core
Core Playground #8EDB5N#2 @babylonjs/core
Core Playground #LL5BIQ#636 @babylonjs/core

@bjsplat

bjsplat commented Aug 18, 2026

Copy link
Copy Markdown
Collaborator

Building or testing the sandbox has failed.

If the tests failed, results can be found here:
https://snapshots-cvgtc2eugrd3cgfd.z01.azurefd.net/SANDBOX/refs/pull/18807/merge/testResults/

1 similar comment
@bjsplat

bjsplat commented Aug 18, 2026

Copy link
Copy Markdown
Collaborator

Building or testing the sandbox has failed.

If the tests failed, results can be found here:
https://snapshots-cvgtc2eugrd3cgfd.z01.azurefd.net/SANDBOX/refs/pull/18807/merge/testResults/

@VicenteCartas
VicenteCartas marked this pull request as draft August 19, 2026 00:30
@bjsplat

bjsplat commented Aug 19, 2026

Copy link
Copy Markdown
Collaborator

Building or testing the sandbox has failed.

If the tests failed, results can be found here:
https://snapshots-cvgtc2eugrd3cgfd.z01.azurefd.net/SANDBOX/refs/pull/18807/merge/testResults/

RaananW pushed a commit to BabylonJS/Documentation that referenced this pull request Aug 24, 2026
## Summary

- Document the new `cameraMinZ` and `cameraLowerRadiusLimit` Sandbox URL
parameters
- Describe validation ranges, scene-unit semantics, camera restrictions,
and local-preset interaction
- Add a working close-up inspection example

Companion to BabylonJS/Babylon.js#18807.

## Validation

- Full page serialized successfully through the production
`next-mdx-remote` pipeline
- Documented asset URL returns HTTP 200

Co-authored-by: Vicente Cartas Espinel <vicente.cartas@microsoft.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
VicenteCartas added a commit to BabylonJS/Documentation that referenced this pull request Aug 24, 2026
> 🤖 *This PR was created by the create-pr skill.*

## Summary
- Revert Documentation PR #1609 while Babylon.js PR #18807 remains under
discussion.
- Remove the unpublished camera preset and `cameraMinZ` /
`cameraLowerRadiusLimit` documentation from the live Sandbox page.

## Motivation
The documentation was merged before the corresponding Babylon.js feature
was accepted and merged. This keeps the published documentation aligned
with the currently released Sandbox.

The removed documentation should be re-landed once the implementation
discussion in BabylonJS/Babylon.js#18807 is
resolved and the feature is merged.

## Validation
- `npm run validate:content` passed with 805 Markdown files and 0
errors.
- `npm run build` passed and generated all 1,402 pages.
- Documentation tests: 79/80 passed; the sole failure is the
pre-existing Windows path-separator assertion in
`content-graph.test.ts`.
- Revert independently reviewed and verified byte-exact against squash
commit `5cdc704f` from
#1609.

Co-authored-by: Vicente Cartas Espinel <vicente.cartas@microsoft.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants